package cz.fimuni.pa165.frontend;

import cz.fimuni.pa165.backendapi.dto.CarDTO;
import cz.fimuni.pa165.backendapi.dto.CompanyDTO;
import cz.fimuni.pa165.backendapi.dto.EmployeeDTO;
import cz.fimuni.pa165.backendapi.dto.ReservationDTO;
import cz.fimuni.pa165.backendapi.facade.ServiceFacade;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

/**
 *
 * @author Lukáš Slovák
 */

@Controller
public class CompanyController {
    
    @Autowired
    private ServiceFacade facade;
    
    @RequestMapping(value="/companies")
    public String companyHome(Model model,
                              HttpServletRequest request){
        HttpSession session = request.getSession();
        processSesionByHome(session, model);
        
        List<CompanyDTO> list = facade.getAllCompanies();
        model.addAttribute("companies", list);
        return "company/list";
    }
       
    @RequestMapping(value="/companyAdd")
    public String addCompany(@RequestParam(value="input1") String input1,
                             @RequestParam(value="input2") String input2,
                             HttpServletRequest request){
        if (companyExists(input1)){
            request.getSession().setAttribute("errMessage1", "list.err3");
            return "redirect:/companies";
        }
        boolean somethingIsMissing = false;
        input1 = input1.trim();
        input2 = input2.trim();
        if (input1.equals("")){
            request.getSession().setAttribute("errMessage1", "list.err1");
            somethingIsMissing = true;
            if (!input2.equals("")){
                request.getSession().setAttribute("input2", input2);
            }
        }
        if (input2.equals("")){
            request.getSession().setAttribute("errMessage2", "list.err2");
            somethingIsMissing = true;
            if (!input1.equals("")){
                request.getSession().setAttribute("input1", input1);
            }
        }
        if (!somethingIsMissing){
            CompanyDTO comp = new CompanyDTO();
            comp.setName(input1);
            comp.setAdress(input2);
            facade.addCompany(comp);
        }
           
        return "redirect:/companies";
    }
    
    @RequestMapping(value="/companyDelete/{id}")
    public String deleteCompany(@PathVariable(value="id") String id,
                                Model model){
        
        CompanyDTO comp = null;
        try {
            comp = facade.getCompanyById(new Long(id));
            if (comp == null){
                return error("error.err", model);
            }
            facade.removeCompany(comp);
            return "redirect:/companies";
        } catch (NumberFormatException e) {
             return error("error.err", model);
        } catch (JpaSystemException e){
            List<CarDTO> dtoList = facade.getAllCars();
            for (int i = 0; i < dtoList.size(); i++) {
                if (dtoList.get(i).getCompany().getId().equals(comp.getId())) {
                    try {
                        deleteCar(dtoList.get(i));
                    } catch (JpaSystemException ex) {
                        return error("error.car", model);
                    }
                }
            }
            
            List<EmployeeDTO> listEmp = facade.findEmployeesByCompany(comp);
            for (int i = 0; i < listEmp.size(); i++){
                EmployeeDTO emp = listEmp.get(i);
                try{
                    deleteEmployee(emp);
                }catch (JpaSystemException ex){
                    return error("error.employee", model);
                }     
            }
            try{
                facade.removeCompany(comp);
                return "redirect:/companies";
            }catch (JpaSystemException ex){
                return error("error.company", model);
            }
        }
    }
    
    @RequestMapping(value="/companyEditJSP/{id}")
    public String companyEditJSP(@PathVariable(value="id") String id,
                                 Model model,
                                 HttpServletRequest request){
        long l = 0;
        try {
            l = Long.parseLong(id);
        } catch (Exception ex) {
            if (id.equals("j_spring_security_logout")){
                return "redirect:/j_spring_security_logout";
            } else {
                return "redirect:/companies";
            }
        }
        try {
            CompanyDTO comp = facade.getCompanyById(new Long(id));
            if (comp == null){
                return error("error.err", model);
            }else{
                HttpSession session = request.getSession();
                String errMessage1 = (String) session.getAttribute("errMessage1");
                String errMessage2 = (String) session.getAttribute("errMessage2");
                if((errMessage1 != null) || (errMessage2 != null)){
                    processSessionByEdit(session, comp, model); 
                }        
                model.addAttribute("company", comp);
                return "company/edit";
            }    
        } catch (NumberFormatException e) {
            return error("error.err", model);
        }
    }
    
    @RequestMapping(value="/companyEdit")
    public String companyEdit(@RequestParam(value="id") String id,
                              @RequestParam(value="name") String name,
                              @RequestParam(value="adress") String adress,
                              HttpServletRequest request){
        if (otherCompanyExists(name, new Long(id))){
            request.getSession().setAttribute("errMessage1", "list.err3");
            request.getSession().setAttribute("name", name);
            request.getSession().setAttribute("adress", adress);
            return "redirect:/companyEditJSP/"+id;
        }
        boolean somethingIsMissing = false;
        name = name.trim();
        adress = adress.trim();
        if (name.equals("")){
            request.getSession().setAttribute("errMessage1", "list.err1");
            somethingIsMissing = true;
            if (!adress.equals("")){
                request.getSession().setAttribute("adress", adress);
            }
        }
        if (adress.equals("")){
            request.getSession().setAttribute("errMessage2", "list.err2");
            somethingIsMissing = true;
            if (!name.equals("")){
                request.getSession().setAttribute("name", name);
            }
        }
        if (! somethingIsMissing){
            CompanyDTO comp = new CompanyDTO();
            comp.setId(new Long(id));
            comp.setName(name);
            comp.setAdress(adress);
            facade.updateCompany(comp);
            return "redirect:/companies";
        }else{
            return "redirect:/companyEditJSP/"+id;
        } 
    }
    
    public String error(String message,
                        Model model){
        model.addAttribute("errMessage", message);
        return "company/companyError";
    }
    
    
    /**
     * Vytiahne atribúty zo session, chybové hlásenia dá do modelu,
     * údaje o firme dá do objektu typu CompanyDTO a vymaže atribúty zo session
     * @param session session, z ktorej vyberie atribúty
     * @param model model, do ktorého ich vloží
     * @param comp objekt typu CompanyDTO, v ktorom sa prenášajú údaje o firme
     */
    private void processSessionByEdit(HttpSession session, CompanyDTO comp, Model model) {
        String errMessage1 = (String) session.getAttribute("errMessage1");
        String errMessage2 = (String) session.getAttribute("errMessage2"); 
        String name = (String) session.getAttribute("name"); 
        String adress = (String) session.getAttribute("adress"); 
        session.removeAttribute("errMessage1");
        session.removeAttribute("errMessage2");
        session.removeAttribute("name");
        session.removeAttribute("adress");
        if (errMessage1 != null){
            model.addAttribute("errMessage1", errMessage1);
        }
        if (errMessage2 != null){
            model.addAttribute("errMessage2", errMessage2);
        }
        if (name != null){
            comp.setName(name);
        }else{
            comp.setName("");
        }
        if (adress != null){
            comp.setAdress(adress);
        }else{
            comp.setAdress("");
        }
    }

    /**
     * Vyberie atribúty zo session, pridá ich do modelu a vymaže zo session
     * @param session session, z ktorej vyberie atribúty
     * @param model model, do ktorého ich vloží
     */
    private void processSesionByHome(HttpSession session, Model model) {
        String errMessage1 = (String) session.getAttribute("errMessage1");
        String errMessage2 = (String) session.getAttribute("errMessage2"); 
        String input1 = (String) session.getAttribute("input1"); 
        String input2 = (String) session.getAttribute("input2"); 
        session.removeAttribute("errMessage1");
        session.removeAttribute("errMessage2");
        session.removeAttribute("input1");
        session.removeAttribute("input2");
        if (errMessage1 != null){
            model.addAttribute("errMessage1", errMessage1);
        }
        if (errMessage2 != null){
            model.addAttribute("errMessage2", errMessage2);
        }
        if (input1 != null){
            model.addAttribute("input1", input1);
        }
        if (input2 != null){
            model.addAttribute("input2", input2);
        }
    }

    private boolean companyExists(String name) {
         List<CompanyDTO> list = facade.getAllCompanies();
         for(CompanyDTO comp : list){
             if( (comp.getName().equals(name)) ){ return true;}
         }
         return false;
    }

    private boolean otherCompanyExists(String name, Long id) {
        List<CompanyDTO> list = facade.getAllCompanies();
         for(CompanyDTO comp : list){
             if( (comp.getName().equals(name)) &&
                 (!comp.getId().equals(id))   ){
                    return true;
             }
         }
         return false;
    }
    
    private void deleteCar(CarDTO car) throws JpaSystemException{
        List<ReservationDTO> dtoList = facade.getAllReservations();
        for (int i = 0; i < dtoList.size(); i++) {
            if (dtoList.get(i).getCar().getId().equals(car.getId())) {
                    facade.removeReservation(dtoList.get(i));                    
            }
        }
        facade.removeCar(car);  
   }
    
    private void deleteEmployee(EmployeeDTO emp) throws JpaSystemException{
        List<ReservationDTO> listRes = facade.getReservationByEmployee(emp);
        for (int j = 0; j < listRes.size(); j++){
            facade.removeReservation(listRes.get(j));
        }
        facade.removeEmployee(emp);
    }
}